import fitz  # PyMuPDF
from PIL import Image
import io


def convert_to_monochrome(image_bytes):
    # Open the image with Pillow
    image = Image.open(io.BytesIO(image_bytes))
    # Convert to monochrome (1-bit pixels, black and white)
    image = image.convert('1')
    # Save to bytes
    output = io.BytesIO()
    image.save(output, format='PNG')
    return output.getvalue()


def split_and_rebuild_pdf(input_pdf_path, output_pdf_path, image_resolution=150):
    # Open the input PDF
    pdf_document = fitz.open(input_pdf_path)
    # Create a new PDF for the output
    new_pdf_document = fitz.open()

    for page_num in range(len(pdf_document)):
        # Get the page
        page = pdf_document.load_page(page_num)
        # Get the page dimensions
        rect = page.rect
        # Define the width and height of the split pages
        width = rect.width / 2
        height = rect.height

        # Define rectangles for left and right halves
        left_rect = fitz.Rect(0, 0, width, height)
        right_rect = fitz.Rect(width, 0, rect.width, height)

        # Create images for each half with downsampling
        pix_left = page.get_pixmap(clip=left_rect, matrix=fitz.Matrix(image_resolution / 72, image_resolution / 72),
                                   alpha=False)
        pix_right = page.get_pixmap(clip=right_rect, matrix=fitz.Matrix(image_resolution / 72, image_resolution / 72),
                                    alpha=False)

        # Convert pixmaps to PNG bytes
        pix_left_bytes = pix_left.tobytes('png')
        pix_right_bytes = pix_right.tobytes('png')

        # Convert PNG bytes to monochrome
        pix_left_monochrome = convert_to_monochrome(pix_left_bytes)
        pix_right_monochrome = convert_to_monochrome(pix_right_bytes)

        # Create temporary PDFs from monochrome images
        img_pdf_left = fitz.open()
        img_pdf_right = fitz.open()

        # Add images as pages in temporary PDFs
        img_pdf_left.new_page(width=width, height=height).insert_image(fitz.Rect(0, 0, width, height),
                                                                       stream=pix_left_monochrome)
        img_pdf_right.new_page(width=width, height=height).insert_image(fitz.Rect(0, 0, width, height),
                                                                        stream=pix_right_monochrome)

        # Append temporary PDFs to the new PDF
        new_pdf_document.insert_pdf(img_pdf_left)
        new_pdf_document.insert_pdf(img_pdf_right)

        # Close temporary PDFs
        img_pdf_left.close()
        img_pdf_right.close()

    # Save the new PDF with optimized compression
    new_pdf_document.save(output_pdf_path, garbage=4, deflate=True, clean=True)
    new_pdf_document.close()
    pdf_document.close()


# Paths to the input and output PDFs
input_pdf_path = 'input.pdf'
output_pdf_path = 'output.pdf'

# Run the function with fine-tuned settings
split_and_rebuild_pdf(input_pdf_path, output_pdf_path, image_resolution=150)
